﻿using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Face.Contract;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml.Controls;

namespace CameraControlDemo
{
    public sealed partial class TrainPage : Page
    {
        private static string personGroupId = DateTime.Now.ToString("yyyyMMddHHmmss"), personGroupName = "Master";
        private bool isGroupCreated = false;
        private static List<Guid> faceIds = null;

        //face-sdk-service
        private FaceServiceClient faceService = null;

        public TrainPage()
        {
            InitializeComponent();
            faceIds = new List<Guid>();
            faceService = new FaceServiceClient(Common.Consts.appKey);
        }

        /// <summary>
        /// 拍照
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnCapture_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            if (!isGroupCreated)
            {
                await faceService.CreatePersonGroupAsync(personGroupId, personGroupName);
                isGroupCreated = true;
            }

            //M1:CameraCaptureUI
            CameraCaptureUI capture = new CameraCaptureUI();
            capture.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
            capture.PhotoSettings.AllowCropping = false;
            try
            {
                StorageFile photo = await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);
                if (photo == null)
                {
                    return;
                }
                //SDK ==
                //Stream 转换
                using (Stream stream = File.Open(photo.Path, FileMode.Open))
                {
                    Face[] faces = await faceService.DetectAsync(stream, analyzesAge: true, analyzesGender: true);
                    if (faces.Count()<1)
                    {
                        Output("未检测到人脸，请重试");
                    }
                    System.Diagnostics.Debug.WriteLine("检测到" + faces.Count() + "张脸");
                    //Output("检测到" + faces.Count() + "张脸");
                    foreach (Face item in faces)
                    {
                        System.Diagnostics.Debug.WriteLine("FaceId:" + item.FaceId + ",年龄:" + item.Attributes.Age + ",性别:" + item.Attributes.Gender);
                        Output("FaceId:" + item.FaceId + ",年龄" + item.Attributes.Age + ",性别" + item.Attributes.Gender);
                        faceIds.Add(item.FaceId);
                    }
                }
                string personName = String.IsNullOrEmpty(txtPersonName.Text) ? "Ben" : txtPersonName.Text;
                if (faceIds.Count == Common.Consts.trainPhotosCount)
                {
                    // Define Anna
                    CreatePersonResult p1 = await faceService.CreatePersonAsync(
                        // Id of the person group that the person belonged to
                        personGroupId,
                        faceIds.ToArray(),
                        // Name of the person
                        personName
                    );
                    Output(p1.PersonId + personName + ",创建成功");
                    Person p = new Person { PersonId = p1.PersonId, FaceIds = faceIds.ToArray(), Name = personName };
                    faceIds.Clear();
                }
            }
            catch (ClientException ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        /// <summary>
        /// 选择图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChoose_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
        }

        /// <summary>
        /// 训练
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnTrain_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            await faceService.TrainPersonGroupAsync(personGroupId);
            TrainingStatus trainingStatus = null;
            while (true)
            {
                trainingStatus = await faceService.GetPersonGroupTrainingStatusAsync(personGroupId);
                if (trainingStatus.Status != "running")
                {
                    break;
                }
                await Task.Delay(1000);
            }
            await new MessageDialog("添加成功").ShowAsync();
        }

        private async void btnIdentify_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            CameraCaptureUI capture = new CameraCaptureUI();
            capture.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
            capture.PhotoSettings.AllowCropping = false;
            try
            {
                StorageFile photo = await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);
                if (photo == null)
                {
                    return;
                }
                //BitmapImage bitmapImage = new BitmapImage();
                //using (IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read))
                //{
                //    bitmapImage.SetSource(stream);
                //    imgShow.Source = bitmapImage;
                //}
                //IRandomAccessStream 和 Stream 转换失败 ==
                using (Stream stream = File.Open(photo.Path, FileMode.Open))
                {
                    Face[] faces = await faceService.DetectAsync(stream);
                    if (faces.Count()<1)
                    {
                        Output("未检测到人脸，请重试");
                        return;
                    }
                    Guid[] fIds = faces.Select(f => f.FaceId).ToArray();
                    //
                    IdentifyResult[] results = await faceService.IdentifyAsync(personGroupId, fIds, maxNumOfCandidatesReturned: 1);
                    //
                    foreach (var identifyResult in results)
                    {
                        System.Diagnostics.Debug.WriteLine("Result of face: {0}", identifyResult.FaceId);
                        if (identifyResult.Candidates.Length == 0)
                        {
                            System.Diagnostics.Debug.WriteLine("No one identified");
                            Output("未知");
                        }
                        else
                        {
                            // Get top 1 among all candidates returned
                            Guid candidateId = identifyResult.Candidates[0].PersonId;
                            Person person = await faceService.GetPersonAsync(personGroupId, candidateId);
                            Output("识别结果是 " + person.Name);
                            System.Diagnostics.Debug.WriteLine(" Identified as {0}", person.Name);
                        }
                    }
                }
            }
            catch (ClientException ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Error.Code + ex.Error.Message);
                Output("出现异常，识别失败" + ex.Error.Message);
                //throw;
            }
            catch (Exception ex)
            {
                Output("出现异常，识别失败" + ex.Message);
                //throw;
            }
        }

        private async void Output(string str)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () => { await new MessageDialog(str).ShowAsync(); });
        }
    }
}